//
//  NetWorkTools.swift
//  MicroBlog
//
//  Created by  NorthCity on 15/11/5.
//  Copyright © 2015年  NorthCity. All rights reserved.
//

import UIKit
import AFNetworking
/// HTTP请求方法枚举
enum TcgRequestMethord:String{
    case GET = "GET"
    case POST = "POST"
}
///请求回调,别名
typealias RequestCallBack = (result:AnyObject?,error:NSError?)->()
//MARK: - 网络工具
class NetWorkTools: AFHTTPSessionManager {
//MARK: - 应用程序信息
    private let appKey = "2536149074"
    private let appSecret = "79087fe30b47f906a14bcef0312e1bf4"
    private let redirectUrl = "http://www.baidu.com"
//MARK: - 网络工具单例
    static let sharedTools:NetWorkTools = {
        let tools = NetWorkTools(baseURL: nil)
        tools.responseSerializer.acceptableContentTypes?.insert("text/plain")
        return tools
    }()
}

//MARK: - 用户信息
extension NetWorkTools{
    func loadUserInfo(uid:String,finished:RequestCallBack){
       
//    1 创建参数字典
        var params = [String:AnyObject]()
//    2 处理网络参数
        let urlString = "https://api.weibo.com/2/users/show.json"
        params["uid"] = uid
//    3 token 访问
        tokenRequest(.GET, urlString: urlString, parameters: params, finished: finished)
    }
}
/// 加载微博数据
///
/// - parameter since_id:   若指定此参数，则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0。
/// - parameter max_id:     若指定此参数，则返回ID小于或等于max_id的微博，默认为0。
/// - parameter finished:   完成回调
/// - see: [http://open.weibo.com/wiki/2/statuses/home_timeline](http://open.weibo.com/wiki/2/statuses/home_timeline)
//MARK : - 获取微博数据方法
extension NetWorkTools{
    func loadStatus(sin_id since_id :Int,max_id:Int,finished:RequestCallBack){
        
        //    1 创建参数字典
        var params = [String:AnyObject]()
        //    2 处理网络参数
        let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
        if since_id > 0 {
            params["since_id"] = since_id
        }else if max_id > 0{
            params["max_id"] = max_id - 1
        }
//        3 发起网路请求
        tokenRequest(.GET, urlString: urlString, parameters: params, finished: finished)
        
    }
}
//MARK: - 发布微博
extension NetWorkTools{
    func sendStatus(status:String,image:UIImage?,finished:RequestCallBack){
        //    1 创建参数字典
        var params = [String:AnyObject]()
        //    2 处理网络参数
        params["status"] = status
        //    3 判断是否上传图片
        if image == nil{
        let urlString = "https://api.weibo.com/2/statuses/update.json"
        tokenRequest(.POST, urlString: urlString, parameters: params, finished: finished)
        } else{
            let urlString = "https://upload.api.weibo.com/2/statuses/upload.json"
            let data = UIImagePNGRepresentation(image!)
            upLoad(urlString, data: data!, name: "pic", parames: params, finished: finished)
        }
    }
}

//MARK: - OAuth 相关方法
extension NetWorkTools {
    ///OAuth 授权 URL
    ///- see: [http://open.weibo.com/wiki/Oauth2/authorize](http://open.weibo.com/wiki/Oauth2/authorize)
    var oauthURL: NSURL {
        
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(appKey)&redirect_uri=\(redirectUrl)"
        
        return NSURL(string: urlString)!
    }
    
    /// 加载 AccessToken
    func loadAccessToken(code: String, finished: RequestCallBack) {
        
        let urlString = "https://api.weibo.com/oauth2/access_token"
        
        let params = ["client_id": appKey,
            "client_secret": appSecret,
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": redirectUrl]
        
        request(.POST, URLString: urlString, parameters: params, finished: finished)
    }
}

//MARK: - 封装 AFN 网络方法
extension NetWorkTools {
/// 实现 appendToken
    private func appendToken(inout parameters:[String:AnyObject]?) -> Bool{
        //    1 判定 token 是否有效
        guard let token = UserAccountViewModel.sharedUserAccount.accessToken else {
            return false
        }
        //    2 判断参数字典是否为空
        if parameters == nil{
            parameters = [String:AnyObject]()
        }
        //    3 拼接参数
        parameters!["access_token"] = token
        
        return true
    }
/// 带token 网络请求
private func tokenRequest(method: TcgRequestMethord, urlString: String, var parameters: [String: AnyObject]?, finished: RequestCallBack) {
    //    1 追加 token
    if !appendToken(&parameters){
        finished(result: nil, error: NSError(domain: "cn.itcast.error", code: -1001, userInfo: ["message": "token 为空"]))
        
        return

    }
    //    2 访问网络
    request(method, URLString: urlString, parameters: parameters, finished: finished)
}

///网络请求
private func request(method:TcgRequestMethord,URLString:String,parameters:[String: AnyObject]?,finished:RequestCallBack){
    //        成功回调
    let success = {
        (task:NSURLSessionDataTask, result:AnyObject) -> Void
        in
        finished(result: result,error: nil)
    }
    //        失败回调
    let failure = {
        (task:NSURLSessionDataTask?, error:NSError) -> Void
        in
        print(error)
        finished(result: nil,error: error)
    }
    if method == TcgRequestMethord.GET {
        GET(URLString, parameters: parameters,
            success: success,
            failure:failure)
    }else{
        POST(URLString, parameters: parameters,
            success: success,
            failure: failure)
    }
    
}
/// 上传文件
    private func upLoad(urlString:String,data:NSData,name:String,var parames:[String:AnyObject]?,finished:RequestCallBack){
        
        if !appendToken(&parames){
            finished(result: nil, error: NSError(domain: "com.tcg", code: -1001, userInfo: ["message":"token 不可用"]))
            return
        }
        
        /**
        1. data 要上传文件的二进制数据
        2. name 是服务器定义的字段名称 － 后台接口文档会提示
        3. fileName 是保存在服务器的文件名，但是：现在通常可以`乱写`，后台会做后续的处理
        - 根据上传的文件，生成 缩略图，中等图，高清图
        - 保存在不同路径，并且自动生成文件名
        
        - fileName 是 HTTP 协议定义的属性
        4. mimeType / contentType: 客户端告诉服务器，二进制数据的准确类型
        - 大类型/小类型
        * image/jpg image/gif image/png
        * text/plain text/html
        * application/json
        - 无需记忆
        - 如果不想告诉服务器准确的类型
        * application/octet-stream
        */
     POST(urlString, parameters: parames, constructingBodyWithBlock: {
        (formData) -> Void in
        formData.appendPartWithFileData(data,name:name,fileName:"xxx",mimeType:"application/octet-stream")
        }, success: { (_, result) -> Void in
            finished(result: result, error: nil)
        }) { (_, error) -> Void in
            finished(result: nil,error: error)
        }
        
    }
}

